package com.vivi.codereview.tools;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XmlReviewHandler {

  private static final String XML_COMMENTS = "de:comments";

  private static final String XML_FILES = "de:files";

  private static final String XML_PROJECT = "de:project";

  private static final String XML_FOLDER = "de:folder";

  private static final String XML_FILE = "de:file";

  public Map<String, Set<String>> parseXmlReviewFile(Document document) {
    Map<String, Set<String>> map = new HashMap<String, Set<String>>();
    NodeList mainNode = document.getChildNodes();
    for (int i = 0; i < mainNode.getLength(); i++) {
      if (mainNode.item(i).getNodeName().equals(XML_COMMENTS)) {
        parseCommentsAttribute(mainNode.item(i), map);
      }
    }
    return map;
  }

  private void parseCommentsAttribute(Node commentNode, Map<String, Set<String>> map) {
    NodeList commentSubNodes = commentNode.getChildNodes();
    for (int i = 0; i < commentSubNodes.getLength(); i++) {
      Node commentSubNode = commentSubNodes.item(i);
      if (commentSubNode.getNodeName().equals(XML_FILES)) {
        parseFilesAttribute(commentSubNode, map);
      }
    }
  }

  private void parseFilesAttribute(Node filesNode, Map<String, Set<String>> map) {
    NodeList filesSubNodes = filesNode.getChildNodes();
    for (int i = 0; i < filesSubNodes.getLength(); i++) {
      Node filesSubNode = filesSubNodes.item(i);
      if (filesSubNode.getNodeName().equals(XML_PROJECT)) {
        String project = filesSubNode.getAttributes().getNamedItem("name").getTextContent();
        parseProjectAttribute(filesSubNode, map, project, "");
      }
    }
  }

  private void parseProjectAttribute(Node projectNode, Map<String, Set<String>> map, String project, String currDir) {
    NodeList projectSubNodes = projectNode.getChildNodes();
    for (int i = 0; i < projectSubNodes.getLength(); i++) {
      Node projectSubNode = projectSubNodes.item(i);
      if (projectSubNode.getNodeName().equals(XML_FOLDER)) {
        String folder = projectSubNode.getAttributes().getNamedItem("name").getTextContent();
        parseProjectAttribute(projectSubNode, map, project, currDir + File.separator + folder);
      }
      else if (projectSubNode.getNodeName().equals(XML_FILE)) {
        String file = projectSubNode.getAttributes().getNamedItem("name").getTextContent();
        String filepath = currDir + File.separator + file;
        Log.log("We found this file in review " + filepath, Log.D);
        addFileFromReview(map, project, filepath);
      }
    }
  }

  /**
   * Add the file found, sorted by project.
   * @param map
   * @param project
   * @param file
   */
  private void addFileFromReview(Map<String, Set<String>> map, String project, String file) {
    if (map.containsKey(project)) {
      map.get(project).add(file);
    }
    else {
      Set<String> newSet = new TreeSet<String>();
      newSet.add(file);
      map.put(project, newSet);
    }
  }
}
